#include <iostream>
#include <cerrno> //errno.h
#include <cstring> //string.h
#include <unistd.h>
#include <string>
#include <sys/wait.h>
#include <sys/types.h>
// fork之后子进程是能拿到父进程的数据的 --- 通信吗？写时拷贝，对方都看不到
// char buffer[1024]; // 定义一个buf，一个从缓冲区里写，一个从缓冲区里读；是不行的；一写就写时拷贝，一写时拷贝就分开了，就无法传递信息。

const int size=1024;
//展示动态信息
std::string getOtherMessage()
{
    static int cnt=0;
    std::string messageid=std::to_string(cnt);
    cnt++;
    pid_t self_id = getpid();
    std::string stringid=std::to_string(self_id);
    std::string message="messageid:";
    message+=messageid;
    message+="my pid is:";
    message+=stringid;

    return message;
}

//子进程进行写入
void SubProcessWrite(int wfd){
    int pipesize=0;
    std::string message = "father,I am a son process";
    char c='A';
    while(true)
    {
        std::cerr << "+++++++++++++++++++++++++++++++++" << std::endl;
        std::string info = message + getOtherMessage();//这条消息就是发给父进程的消息
        write(wfd,info.c_str(),info.size()); //写入管道的时候，有没有写入\0,,有没有必要？没有必要
        sleep(1); //子进程写的越慢，父进程读的也越慢
         
        // write(wfd, &c, 1);
        // std::cout << "pipesize: " << ++pipesize << " write charator is : "<< c++ << std::endl;
        // if(c == 'G') break; //测试管道第三种情况，读端一直读，写端关闭wfd
        // sleep(1);

    }
    std::cout << "child quit ..." <<std::endl;
}
//父进程进行读取
void FatherProcessRead(int rfd)
{
    char inbuffer[size];//c99 , gnu g99
    while(true){
       ssize_t n = read(rfd,inbuffer,sizeof(inbuffer));
       if(n>0)
       {
        inbuffer[n]=0; // == '\0'
        std::cout << "father get message" << inbuffer << std::endl;
       }
       // 如果read的返回值是0，表示写端直接关闭了，我们读到了文件的结尾
       else if(n==0)
       {
        std::cout << "client quit, father get return val:" << n << "father quit too !" << std::endl;
        break;
       }
       else if(n<0)//读失败了
       {
        std::cerr << "read error!" << std::endl;

        break;
       }

       break;
    }
}

int main()
{

    //1.创建管道
    int pipefd[2];
    int n=pipe(pipefd);
    if(n!=0){
        std::cerr << "errno:" << errno << ":" << "errstring" << strerror(errno) << std::endl;
        return 1;
    }
    //pipefd[0]-->0->r(读) pipefd[1]-->1->w(写) 
    std::cout << "pipefd[0]:" << pipefd[0] << '\n' << "pipefd[1]" << pipefd[1] << std::endl;
    sleep(1);
    //2.创建子进程
    
    pid_t id =fork();
    if(id == 0){
        //子进程
        //3.关闭不需要的fd
        std::cout << "子进程关闭不需要的fd了,准备发消息了" << std::endl;
        sleep(1);
        close(pipefd[0]);
        SubProcessWrite(pipefd[1]);
        close(pipefd[1]);
        exit(0);
    }
    std::cout << "父进程关闭不需要的fd了,准备收消息了" << std::endl;
    sleep(1);


    //父进程 --- read
    //3.关闭不需要的fd
     close(pipefd[1]); 
     FatherProcessRead(pipefd[0]);
     std::cout << "5s,father close fd" << std::endl;
     sleep(5);
     close(pipefd[0]); 
     int status = 0; 
     //pid_t rid =waitpid(id,nullptr,0);
     pid_t rid = waitpid(id,&status,0); 
     if(rid>0){
        std::cout << "wait child process done,exit sig:" << (status&0x7f) << std::endl;//查看返回信号，和返回的错误码。
        std::cout << "wait child process done,exit code(ign):" << ((status>>8)&0xFF) << std::endl;
     }
     
    return 0;

}